package cn.tianya.irock.security;

import javax.servlet.http.Cookie;

import cn.tianya.irock.core.DateTime;
import cn.tianya.irock.core.HttpContext;
import cn.tianya.irock.util.HexUtil;


public class FormsAuthentication {
	
	public static final String COOKIE_NAME = ".ROCKAUTH";
	static String authConfigPath = "/authentication";
	static String cookiePath;
	static boolean initialized = false;
	static int timeout;
	static Object locker = new Object ();
	
	public static void initialize () {
		if (initialized)
			return;
		timeout = 30;
		cookiePath = "/";
		initialized = true;
	}
	
	public static String encrypt (FormsAuthenticationTicket ticket)	{
		if (ticket == null)
			throw new NullPointerException ("ticket");
		
		initialize();
		StringBuilder allTicket = new StringBuilder ();
		allTicket.append (ticket.getVersion());
		allTicket.append ('\u0001');
		allTicket.append (ticket.getName());
		allTicket.append ('\u0001');
		allTicket.append (ticket.getIssueDate().getDate().getTime());
		allTicket.append ('\u0001');
		allTicket.append (ticket.getExpiration().getDate().getTime());
		allTicket.append ('\u0001');
		allTicket.append (ticket.isPersistent() ? '1' : '0');
		allTicket.append ('\u0001');
		allTicket.append (ticket.getUserData());
		allTicket.append ('\u0001');
		allTicket.append (ticket.getCookiePath());
		allTicket.append ('\u0001');
		
		return HexUtil.getHexString (allTicket.toString());
	}
	
	public static FormsAuthenticationTicket decrypt (String encryptedTicket) {
		if (encryptedTicket == null || encryptedTicket.length() == 0)
			throw new NullPointerException ("Invalid encrypted ticketencryptedTicket");

		byte [] bytes = HexUtil.getBytes (encryptedTicket, encryptedTicket.length());
		String decrypted = null;//bytes.toString();//Encoding.ASCII.GetString (bytes);
		FormsAuthenticationTicket ticket = null;
		try {
			//String [] values = decrypted.split ((char) 1, (char) 2, (char) 3, (char) 4, (char) 5, (char) 6, (char) 7);
			decrypted = new String(bytes, "UTF-8");
			String [] values = decrypted.split("\u0001");
			if (values.length != 7)
				throw new Exception (values.length + " " + encryptedTicket);


			ticket = new FormsAuthenticationTicket (Integer.parseInt(values[0]),
								values [1],
								new DateTime (Long.parseLong(values[2])),
								new DateTime (Long.parseLong(values[3])),
								(values[4].equals("1")),
								values [5],
								values [6]);
		} catch (Exception ex) {
			ticket = null;
		}

		return ticket;
	}
	
	public static void signOut() {
		initialize ();
		
		Cookie cookie = HttpContext.current().request().getCookie(COOKIE_NAME);
		if (cookie == null)
			return;
		
		cookie.setValue("");
		cookie.setMaxAge(0);
		HttpContext.current().response().addCookie(cookie);
		HttpContext.current().setUser(new GenericPrincipal (new GenericIdentity ("", ""), new String [0]));
	}
	
	public static FormsAuthenticationTicket getAuthTicket(String userName, boolean createPersistentCookie) {
		initialize ();

		if (userName == null)
			userName = "";

		DateTime now = DateTime.now();
		DateTime then;
		if (createPersistentCookie)
			then = now.addYears (50);//DateTime.diff(now.addYears (50), DateTime.now());
		else
			then = now.addMinutes (timeout);//DateTime.diff(now.addMinutes (timeout), DateTime.now());

		FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (1,
										  userName,
										  now,
										  then,
										  createPersistentCookie,
										  "",
										  cookiePath);
		
		return ticket;
	}
	
	public static Cookie getAuthCookie (String userName, boolean createPersistentCookie) {
		return getAuthCookie (userName, createPersistentCookie, null);
	}

	public static Cookie getAuthCookie (String userName, boolean createPersistentCookie, String strCookiePath) {
		FormsAuthenticationTicket ticket = getAuthTicket(userName, createPersistentCookie);
		
		if (strCookiePath == null || strCookiePath.length() == 0)
			strCookiePath = cookiePath;
				
		Cookie c = new Cookie(COOKIE_NAME, encrypt (ticket));
		c.setPath(strCookiePath);
		c.setMaxAge((int)ticket.getExpiration().getTime());
		return c;
	}
	
	public static Cookie getAuthCookie (FormsAuthenticationTicket ticket, String strCookiePath) {
		if (strCookiePath == null || strCookiePath.length() == 0)
			strCookiePath = cookiePath;
		
		Cookie c = new Cookie(COOKIE_NAME, encrypt (ticket));
		c.setPath(strCookiePath);
		c.setMaxAge((int)ticket.getExpiration().getTime());
		return c;
	}
	
	public static void setAuthCookie (String userName, boolean createPersistentCookie) {
		initialize ();
		setAuthCookie (userName, createPersistentCookie, cookiePath);
	}

	public static void setAuthCookie (String userName, boolean createPersistentCookie, String strCookiePath) {
		FormsAuthenticationTicket ticket = null;
		Cookie cookie = null;
		HttpContext context = null;
		
		context = HttpContext.current();
		ticket = getAuthTicket(userName, createPersistentCookie);
		cookie = getAuthCookie(ticket, strCookiePath);
		cookie.setDomain(context.request().getSimpleServerName());
		context.setUser(new GenericPrincipal (new FormsIdentity (ticket), new String [0]));
		context.response().addCookie(cookie);
	}
}
